package controller

import (
	"bluebell_qimi/logic"
	"bluebell_qimi/models"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"strconv"
)

// 创建帖子的处理函数
func CreatePostHandler(c *gin.Context) {
	p := new(models.Post)
	//1. 获取参数及参数的校验
	//ShouldBindJSON(p)  会自动校验tag,validator-->binding tag
	if err := c.ShouldBindJSON(p); err != nil {
		zap.L().Debug("c.shouldBindJSON(p) error", zap.Any("err", err))
		zap.L().Error("create post with invalid param")
		ResponseError(c, CodeInvalidParam)
		return
	}

	//2. 创建帖子
	//从c中取到当前发送请求的用户的id，auth.go中
	//将当前请求的userid信息保存到请求的上下文c上
	//c.Set(controller.CtxUserIDKey, mc.UserID)
	//然后通过request.go中getCurrentUser获取当前用户id
	userID, err := getCurrentUserID(c)
	if err != nil {
		ResponseError(c, CodeNeedLogin)
		return
	}
	p.AuthorID = userID

	if err := logic.CreatePost(p); err != nil {
		zap.L().Error("logic.CreatePost(p) failed", zap.Error(err))
		ResponseError(c, CodeServerBusy) //不让用户看到报错信息
		return
	}
	//3. 返回响应
	ResponseSuccess(c, nil)
}

// 根据帖子id获取帖子详情的处理函数
func GetPostDetailHandler(c *gin.Context) {
	//1. 获取参数（从URL中获取帖子的的id）
	idStr := c.Param("id")
	pid, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		zap.L().Debug("get invalid param for post detail", zap.Error(err))
		ResponseError(c, CodeInvalidParam)
		return
	}

	//2. 根据id取出帖子数据（查数据库）
	data, err := logic.GetPostById(pid)
	if err != nil {
		zap.L().Error("logic.GetPostById(pid) failed", zap.Error(err))
		ResponseError(c, CodeServerBusy) //不想要用户看到
		return
	}
	//3. 返回响应
	ResponseSuccess(c, data)
}

// 获取所有帖子列表和详细信息
func GetPostListHandler(c *gin.Context) {
	//获取帖子想要的分页效果
	page, size := getPageInfo(c)
	//获取数据
	data, err := logic.GetPostList(page, size)
	if err != nil {
		zap.L().Error("logic.GetPostList() failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
	}
	//返回响应
	ResponseSuccess(c, data)
}

// GetPostListHandler2 升级版帖子列表接口
// @Summary 升级版帖子列表接口
// @Description 可按社区按时间或分数排序查询帖子列表接口
// @Tags 帖子相关接口
// @Accept application/json
// @Produce application/json
// @Param Authorization header string false "Bearer 用户令牌"
// @Param object query models.ParamPostList false "查询参数"
// @Security ApiKeyAuth
// @Success 200 {object} _ResponsePostList
// @Router /posts2 [get]
// 升级版帖子列表接口，按热度或者时间排序
// 根据前端传来的参数动态地获取帖子列表
// 按照时间排序 或者 按照分数排序
// 1. 获取请求的query string参数
// 2. 去redis查询postid列表
// 3. 根据postid去数据库查询帖子详细信息
func GetPostListHandler2(c *gin.Context) {
	//GET请求参数（query string）：api/va/posts2?page=1&size=10&order=time
	//初始化结构体时指定初始参数
	p := &models.ParamPostList{
		Page:  1,
		Size:  10,
		Order: models.OrderTime, //magic string
	}
	//1. c.ShouldBind()根据请求的数据类型选择相应的方法去获取数据，一般用form表单来进行验证
	//2. c.ShouldBindJSON()如果请求中携带的是json格式的数据，才能用这个方法获取到数据,postman可以用
	// {   "page":1,
	//    "size":2
	//}进行调试
	//3. c.Param("url的a",字段)，可以127.0.0.1:8084/api/v1/community/1来测试
	//4. c.ShouldBindQuery(p)可以查询多个?后面的参数
	//例如127.0.0.1:8084/api/v1/posts2?order=time&size=1&page=1
	if err := c.ShouldBindQuery(p); err != nil {
		zap.L().Error("GetPostListHandler2 c.ShouldBindQuery(p) failed", zap.Error(err))
		ResponseError(c, CodeInvalidParam)
		return
	}
	//获取数据
	data, err := logic.GetPostListNew(p) //更新合二为一
	//data, err := logic.GetPostList2(p)
	if err != nil {
		zap.L().Error("logic.GetPostList() failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
	}
	//返回响应
	ResponseSuccess(c, data)
}

// 根据社区去查询帖子列表
/*func GetCommunityPostListHandler(c *gin.Context) {
	//初始化结构体时指定初始参数
	var p = &models.ParamCommunityPostList{
		ParamPostList: &models.ParamPostList{
			Page:  1,
			Size:  10,
			Order: models.OrderTime,
		},
	}
	//c.ShouldBind()根据请求的数据类型选择相应的方法去获取数据
	//c.ShouldBindJSON()如果请求中携带的是json格式的数据，才能用这个方法获取到数据
	if err := c.ShouldBindQuery(p); err != nil {
		zap.L().Error("ParamCommunityPostList c.ShouldBindQuery(p) failed", zap.Error(err))
		ResponseError(c, CodeInvalidParam)
		return
	}

	//获取数据
	data, err := logic.GetCommunityPostList(p)
	if err != nil {
		zap.L().Error("logic.GetPostList() failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
	}
	//返回响应
	ResponseSuccess(c, data)
}*/

// 根据社区id查帖子
func GetCommunityPostListHandler(c *gin.Context) {
	//初始化结构体时指定初始参数
	p := &models.ParamPostList{
		CommunityID: 0,
		Page:        1,
		Size:        10,
		Order:       models.OrderTime, //magic string
	}
	//c.ShouldBind()根据请求的数据类型选择相应的方法去获取数据
	//c.ShouldBindJSON()如果请求中携带的是json格式的数据，才能用这个方法获取到数据
	//GET请求参数（query string）：127.0.0.1:8084/api/v1/posts3?page=1&size=10&order=time&community_id=2
	if err := c.ShouldBindQuery(p); err != nil {
		zap.L().Error("GetCommunityPostListHandler c.ShouldBindQuery(p) failed", zap.Error(err))
		ResponseError(c, CodeInvalidParam)
		return
	}
	//获取数据
	data, err := logic.GetPostListNew(p) //更新合二为一
	//data, err := logic.GetPostList2(p)
	if err != nil {
		zap.L().Error("logic.GetPostList() failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
	}
	//返回响应
	ResponseSuccess(c, data)
}
